
#ifndef RTMP_INCLUDE_PARSER_H_
#define RTMP_INCLUDE_PARSER_H_

#ifndef RTMP_INCLUDE_MESSAGE_H_
#include "rtmp_message.h"
#endif
#include <cstdint>
#include <memory>
#include <vector>
#include "./../../public_module/public_module_define.h"

class RtmpMessageBuffer;

class RtmpParser
{
public:
    RtmpParser();
    ~RtmpParser();
    std::shared_ptr<RtmpMessage> ParseRtmpMessage(const uint8_t * data, int length, int & use_length, int status);
    int GetChunkSize();
private:
    int ProcessHeader(const uint8_t * data, int header_length, std::shared_ptr<RtmpMessage> & message);
    int ProcessBody(const uint8_t   * data, int length, std::shared_ptr<RtmpMessage> & message);
    int SwitchBodyCommand(std::shared_ptr<RtmpMessage> & message);
    int ParseMetaData(std::shared_ptr<RtmpMessage> & message);
    int ParseVideoData(std::shared_ptr<RtmpMessage> & message);
    int ParseAudioData(std::shared_ptr<RtmpMessage> & message);
    int ParseBodyData(std::shared_ptr<RtmpMessage> & message);
private:
    std::map<int, int> m_header_length_map;
    uint32_t             m_chunk_size;
    std::vector<uint8_t> m_data;
    std::shared_ptr<RtmpMessage> m_rtmp_msg; 
	std::map<int, RtmpStreamData> m_rtmp_stream_map;
};

class RtmpMessageCompose
{
public:
    RtmpMessageCompose(RtmpParser * parser);
    ~RtmpMessageCompose();
    int ComposeRtmpMessage(std::shared_ptr<RtmpMessage> & msg);
    int ChunkBlockSize();
    void GetData(std::vector<uint8_t> & buffer);
private:
    int ComposeHeader(RtmpHeader & header, int index);
    void ComposeRtmpMessageAttrData(std::shared_ptr<RtmpMessage> & msg, std::vector<uint8_t> & buffer);
private:
    std::map<int, int> m_header_length_map;
    /* uint8_t m_chunk_size; */
    RtmpParser * m_rtmp_parser{nullptr};
    std::map<int, WriteBuffer> m_index_buffer;
private:
    int m_chunk_size;
};

class RtmpMessageBuffer
{
public:
    RtmpMessageBuffer();
    ~RtmpMessageBuffer();
    int PushDataToBuffer(const uint8_t * data, int length, int & use_length);
    int MsgSize();
    std::shared_ptr<RtmpMessage> PopMsg();
    int ComposeRtmpMessage(std::shared_ptr<RtmpMessage> & msg);
    void GetData(std::vector<uint8_t> & buffer);
private:
    RtmpParser m_parser;
    RtmpMessageCompose * m_compose;
    std::vector<std::shared_ptr<RtmpMessage>> m_message_vec;
};


class RtmpPacketDump
{
public:
	static void RtmpPacketDumpInfo(std::shared_ptr<RtmpMessage> message);
};

#endif
